<html>
<head><meta charset="utf-8"><title>floating point semantics · t-lang · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/index.html">t-lang</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/floating.20point.20semantics.html">floating point semantics</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="194504960"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/floating%20point%20semantics/near/194504960" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/floating.20point.20semantics.html#194504960">(Apr 17 2020 at 21:53)</a>:</h4>
<p>I'm working on writing up the (long) comment summarizing the state of the floating point to integer casts, and I'm having trouble nailing down exactly how to interpret what C++ does.</p>



<a name="194505087"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/floating%20point%20semantics/near/194505087" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/floating.20point.20semantics.html#194505087">(Apr 17 2020 at 21:54)</a>:</h4>
<p>I believe <a href="https://en.cppreference.com/w/c/language/conversion#Real_floating-integer_conversions" title="https://en.cppreference.com/w/c/language/conversion#Real_floating-integer_conversions">https://en.cppreference.com/w/c/language/conversion#Real_floating-integer_conversions</a> is a reasonable reference, and AFAICT given Rust's lack of support for rounding modes, we basically can boil that down to C++ rounding to nearest for imprecisely representable values and otherwise being undefined</p>



<a name="194505169"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/floating%20point%20semantics/near/194505169" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/floating.20point.20semantics.html#194505169">(Apr 17 2020 at 21:55)</a>:</h4>
<p>(AFAICT, this differs from the behavior given by LLVM's fptoui which rounds to zero; as well as the behavior Rust currently has regardless of -Zsaturating-float-casts)</p>



<a name="194505390"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/floating%20point%20semantics/near/194505390" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/floating.20point.20semantics.html#194505390">(Apr 17 2020 at 21:57)</a>:</h4>
<p>Also, does Rust require IEEE arithmetic to be supported? I somehow feel that the answer is yes... but maybe that's not true</p>



<a name="194510379"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/floating%20point%20semantics/near/194510379" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/floating.20point.20semantics.html#194510379">(Apr 17 2020 at 23:03)</a>:</h4>
<p>pretty sure Rust is iEEE-only</p>



<a name="194510382"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/floating%20point%20semantics/near/194510382" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> eddyb <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/floating.20point.20semantics.html#194510382">(Apr 17 2020 at 23:03)</a>:</h4>
<p>cc <span class="user-mention" data-user-id="124289">@Hanna Kruppe</span></p>



<a name="194511661"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/floating%20point%20semantics/near/194511661" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/floating.20point.20semantics.html#194511661">(Apr 17 2020 at 23:22)</a>:</h4>
<p>I would love to have options to <em>not</em> be, but yes, at the moment it is.</p>



<a name="194511672"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/floating%20point%20semantics/near/194511672" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/floating.20point.20semantics.html#194511672">(Apr 17 2020 at 23:22)</a>:</h4>
<p>(<em>cough</em> FMA <em>cough</em>)</p>



<a name="194534120"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/floating%20point%20semantics/near/194534120" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hanna Kruppe <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/floating.20point.20semantics.html#194534120">(Apr 18 2020 at 08:55)</a>:</h4>
<p>FWIW, I wouldn't say contraction (license to form FMAs from fadds and fmuls) is "not IEEE". The standard mostly describes a set of operations, how program source code in various languages maps to these operations is not really within its jurisdiction. When it does talk about language implementations, it is almost entirely non-binding (lots of "should" and "may"). In particular, §10.3 (2019 version) discusses "value-changing optimizations", even listing contraction as one example of such optimization (and the list  there is explicitly not exhaustive).</p>



<a name="194534260"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/floating%20point%20semantics/near/194534260" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hanna Kruppe <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/floating.20point.20semantics.html#194534260">(Apr 18 2020 at 08:58)</a>:</h4>
<p><span class="user-mention" data-user-id="116122">@simulacrum</span> First of all, I'm confused by the rounding mode stuff: Rust does not have support for users selecting non-default rounding modes, but certainly we can and should define certain operations to have a (fixed) rounding mode different from RNE.</p>



<a name="194534707"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/floating%20point%20semantics/near/194534707" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hanna Kruppe <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/floating.20point.20semantics.html#194534707">(Apr 18 2020 at 09:11)</a>:</h4>
<p>As for "does Rust require IEEE arithmetic to be supported" ... it's complicated. The reference has long said our <code>f32</code> and <code>f64</code> types map to IEEE 754 (version unspecified) binary32 and binary64 formats, but that's technically a statement about storage layout, not how arithmetic is performed. On most targets, each Rust-source-level operation takes the results in the obvious format and rounds the result to the same format. But on a few targets (e.g. x86 w/o SSE2), multiple operation can and are performed in an intermediate format and rounded at the end, which can give different results. Some other hardware we support flushes denormal results to zero or otherwise is fuzzy around denormals (typically configurable, but we don't fiddle with it).</p>
<p>We don't have an official policy on these things one way or another, but they're certainly not what the average programmer will expect when told "Rust floats are IEEE 754, end of story".</p>



<a name="194538442"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/floating%20point%20semantics/near/194538442" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/floating.20point.20semantics.html#194538442">(Apr 18 2020 at 10:54)</a>:</h4>
<p>Yeah, when I said lack of support I meant that there's no way to switch in std, and I seem to recall an issue saying that there was some undefined behavior involved</p>



<a name="194559081"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/floating%20point%20semantics/near/194559081" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/floating.20point.20semantics.html#194559081">(Apr 18 2020 at 19:04)</a>:</h4>
<p><span class="user-mention" data-user-id="124289">@Hanna Kruppe</span> I agree that contraction should be perfectly fine, but the last time that came up, there was huge pushback against the idea on the grounds that it'd be somehow standards-violating.</p>



<a name="194559276"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/floating%20point%20semantics/near/194559276" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hanna Kruppe <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/floating.20point.20semantics.html#194559276">(Apr 18 2020 at 19:09)</a>:</h4>
<p>Not only on those grounds, to be clear. But if this particular argument comes up in future discussions and I have the time to participate, I'll probably end up writing a very pedantic standards lawyering rebuttal. (Not that I expect it'll really change anyone's mind.)</p>



<a name="194559703"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/floating%20point%20semantics/near/194559703" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/floating.20point.20semantics.html#194559703">(Apr 18 2020 at 19:21)</a>:</h4>
<p>I would appreciate that, thank you.</p>



<a name="194559708"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/floating%20point%20semantics/near/194559708" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/floating.20point.20semantics.html#194559708">(Apr 18 2020 at 19:21)</a>:</h4>
<p>(And yes, I'm aware that there was pushback on other grounds as well.)</p>



<a name="194584801"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/floating%20point%20semantics/near/194584801" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/floating.20point.20semantics.html#194584801">(Apr 19 2020 at 07:53)</a>:</h4>
<p>contraction is just one example of a "fast-math"-style optimization, right? I'd also be quite concerned if we did those by default, mostly because so far we barely know how to <em>specify</em> them formally in the context of a whole programming language, let alone argue that a compiler is following the spec. all I know of is a single work-in-progress unpublished proposal (by colleagues at MPI-SWS :D ), but the design space is big.<br>
so as far as I am concerned, the issue isnt that it violates some standards, the issue is that <em>there is no standard</em> and we dont even really know how to write one (with a level of mathematical precision that I would find satisfying).</p>



<a name="194584805"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/floating%20point%20semantics/near/194584805" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/floating.20point.20semantics.html#194584805">(Apr 19 2020 at 07:53)</a>:</h4>
<p>in terms of the user-visible side of this, I saw some proposals for controlling these optimizations based on the types of the operands, and got to say I quite liked those :D</p>



<a name="194584807"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/floating%20point%20semantics/near/194584807" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/floating.20point.20semantics.html#194584807">(Apr 19 2020 at 07:53)</a>:</h4>
<p>type-based toggles seem much more suited for this than global flags like C compilers use them</p>



<a name="194584919"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/floating%20point%20semantics/near/194584919" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/floating.20point.20semantics.html#194584919">(Apr 19 2020 at 07:57)</a>:</h4>
<p>I should also mention that these aforementioned colleagues expressed interest in exploring their style of fast-math semantics for rust, and asked me how to best proceed with that. I told them to maybe start with a post on IRLO, maybe join here on zulip and start a discussion. not sure how their timetable for that looks.</p>



<a name="194600346"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/floating%20point%20semantics/near/194600346" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/floating.20point.20semantics.html#194600346">(Apr 19 2020 at 14:28)</a>:</h4>
<p><span class="user-mention" data-user-id="120791">@RalfJ</span> In general, I'd suggest completely avoiding the term "fast-math", because it encompasses everything from optimizations that make math more precise (like contraction) to those that lose precision.</p>



<a name="194600882"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/floating%20point%20semantics/near/194600882" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hanna Kruppe <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/floating.20point.20semantics.html#194600882">(Apr 19 2020 at 14:41)</a>:</h4>
<p>I have other qualms with the "fast-math" term (it suggests a performance advantage that is often barely there and does not convey the risks, incentivizing programmers to over-use it and get bitten by it later), but I do think it's justified to have a term that encompasses all of these optimizations. They have substantial overlap -- challenges for reproducibility and standardization, primarily enabled for performance reasons -- even if they differ on other axes and some subsets of them also deserve names.</p>
<p>As for better terms to replace "fast-math", I like the phrases "value-changing optimization" and "(changing/preserving) the literal meaning of the source code" used in IEEE 754-2019.</p>



<a name="194601061"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/floating%20point%20semantics/near/194601061" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/floating.20point.20semantics.html#194601061">(Apr 19 2020 at 14:44)</a>:</h4>
<p>yeah, I used the term for lack of a better one</p>



<a name="194601076"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/floating%20point%20semantics/near/194601076" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/floating.20point.20semantics.html#194601076">(Apr 19 2020 at 14:44)</a>:</h4>
<p>I think it's worth distinguishing between optimizations that add precision and those that lose precision, as well.</p>



<a name="194601087"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/floating%20point%20semantics/near/194601087" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/floating.20point.20semantics.html#194601087">(Apr 19 2020 at 14:44)</a>:</h4>
<p>FWIW, I'd include using x87 float instructions in there, even though we already do that</p>



<a name="194601187"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/floating%20point%20semantics/near/194601187" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/floating.20point.20semantics.html#194601187">(Apr 19 2020 at 14:46)</a>:</h4>
<p><span class="user-mention silent" data-user-id="239881">Josh Triplett</span> <a href="#narrow/stream/213817-t-lang/topic/floating.20point.20semantics/near/194601076" title="#narrow/stream/213817-t-lang/topic/floating.20point.20semantics/near/194601076">said</a>:</p>
<blockquote>
<p>I think it's worth distinguishing between optimizations that add precision and those that lose precision, as well.</p>
</blockquote>
<p>in terms of user interface (compiler flags etc), definitely. in terms of <em>specification</em>, I am less sure. it is already really hard to specify the envelope of permissible program behavior under such transformations; also requiring that "precision has to increase" (whatever that even means, in general) is yet another can of worms...</p>



<a name="194601230"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/floating%20point%20semantics/near/194601230" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/floating.20point.20semantics.html#194601230">(Apr 19 2020 at 14:47)</a>:</h4>
<p>I could totally imagine situations where contraction locally increases precision but globally decreases it</p>



<a name="194601425"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/floating%20point%20semantics/near/194601425" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/floating.20point.20semantics.html#194601425">(Apr 19 2020 at 14:51)</a>:</h4>
<p>If you define precision in terms of how close you are to the true value, I don't see how that would work. I would love to see a sequence of operations that had that result.</p>



<a name="194601679"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/floating%20point%20semantics/near/194601679" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/floating.20point.20semantics.html#194601679">(Apr 19 2020 at 14:56)</a>:</h4>
<p>Here's a really contrived example: take <code>f1</code> and <code>f2</code> to be twice the same function. Consider <code>f1(x) - f2(x)</code>. If we now optimize <code>f1</code> with contraction but leave <code>f2</code> unchanged, the precision of the overall expression will decrease.</p>



<a name="194601895"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/floating%20point%20semantics/near/194601895" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hanna Kruppe <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/floating.20point.20semantics.html#194601895">(Apr 19 2020 at 15:02)</a>:</h4>
<p>Another example of this (strongly related but not quite an instance of Ralf's template) is x²-y² when x = y, which is brought up every time the topic comes up. I'm starting to worry about how often this happens around FP things (not just contraction, also other FMF and anything related to fp environment access), discussions flaming up again once in a while and re-treading the same facts that were already discovered last time.</p>



<a name="194601914"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/floating%20point%20semantics/near/194601914" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hanna Kruppe <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/floating.20point.20semantics.html#194601914">(Apr 19 2020 at 15:03)</a>:</h4>
<p>And so much of it is buried deep in chat archives where they're unlikely to be found again.</p>



<a name="194602191"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/floating%20point%20semantics/near/194602191" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/floating.20point.20semantics.html#194602191">(Apr 19 2020 at 15:08)</a>:</h4>
<p>what's "FMF"?</p>



<a name="194602214"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/floating%20point%20semantics/near/194602214" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hanna Kruppe <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/floating.20point.20semantics.html#194602214">(Apr 19 2020 at 15:10)</a>:</h4>
<p>fast-math flags, shortened primarily to avoid the evil "fast-math" substring</p>



<a name="194602254"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/floating%20point%20semantics/near/194602254" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/floating.20point.20semantics.html#194602254">(Apr 19 2020 at 15:10)</a>:</h4>
<p>^^</p>



<a name="194602264"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/floating%20point%20semantics/near/194602264" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/floating.20point.20semantics.html#194602264">(Apr 19 2020 at 15:10)</a>:</h4>
<p>it's not just chat archives luckily, there are a bunch of unresolved discussion threads in <a href="https://github.com/rust-lang/rfcs/pull/2686" title="https://github.com/rust-lang/rfcs/pull/2686">https://github.com/rust-lang/rfcs/pull/2686</a> that also pertain to this</p>



<a name="194602267"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/floating%20point%20semantics/near/194602267" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/floating.20point.20semantics.html#194602267">(Apr 19 2020 at 15:10)</a>:</h4>
<p>would be good to get them incorporated in the RFC at some point</p>



<a name="194602269"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/floating%20point%20semantics/near/194602269" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hanna Kruppe <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/floating.20point.20semantics.html#194602269">(Apr 19 2020 at 15:10)</a>:</h4>
<p>(Not really, the acronym is widely used by people who have no such qualms, but that's my personal reason to prefer it :D)</p>



<a name="194603438"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/floating%20point%20semantics/near/194603438" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/floating.20point.20semantics.html#194603438">(Apr 19 2020 at 15:37)</a>:</h4>
<p><span class="user-mention" data-user-id="120791">@RalfJ</span> That's assuming correlation between the imprecision. And in any case, what about if you compile the entire program with contraction enabled?</p>



<a name="194603526"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/floating%20point%20semantics/near/194603526" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hanna Kruppe <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/floating.20point.20semantics.html#194603526">(Apr 19 2020 at 15:39)</a>:</h4>
<p>Oh, but that reminds me: in that thread we discussed how some flags like "no NaNs" can produce undef-like behavior and thus could lead to UB, but I've since realized (and hastily jotted down here: <a href="https://github.com/rust-lang/rust/issues/21690#issuecomment-610459562" title="https://github.com/rust-lang/rust/issues/21690#issuecomment-610459562">https://github.com/rust-lang/rust/issues/21690#issuecomment-610459562</a>) that the same concern applies to basically all value-changing optimizations. That is, <code>%x = &lt;some fp computations&gt;</code> with two uses (e.g. a bounds check and an array indexing) could get duplicated such that one of the uses gets one copy of the computation and the other use gets the other copy, and then the two copies can get optimized differently and result in the same fun effects you get from "every use of <code>undef</code> independently observes a non-det value".</p>
<p>The obvious solution if we're concerned with compiler correctness is "well don't duplicate instructions whose value might be non-deterministic" but given that such duplication is common in various optimizations (and <code>undef</code>/<code>poison</code> are specifically engineered to make them valid in the absence of <code>freeze</code>), this seems hard to swallow. So perhaps the conclusion is that <em>all</em> "fast-math" optimizations are unsafe? And it's not the kind of unsafe where a careful programmer can avoid UB.</p>



<a name="194605921"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/floating%20point%20semantics/near/194605921" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/floating.20point.20semantics.html#194605921">(Apr 19 2020 at 16:25)</a>:</h4>
<p><span class="user-mention silent" data-user-id="239881">Josh Triplett</span> <a href="#narrow/stream/213817-t-lang/topic/floating.20point.20semantics/near/194603438" title="#narrow/stream/213817-t-lang/topic/floating.20point.20semantics/near/194603438">said</a>:</p>
<blockquote>
<p><span class="user-mention silent" data-user-id="120791">RalfJ</span> That's assuming correlation between the imprecision. And in any case, what about if you compile the entire program with contraction enabled?</p>
</blockquote>
<p>I think we definitely have to assume correlation between the imprecision. Assuming they are uncorrelated sounds like a big stretch to me.</p>
<p>sure this particular contrived example is easy to fix. but it demonstrates the principle. precision (in the presence of uncorrelated imprecision) is fundamentally not a monotone or otherwise compositional property, so there is just no way to reason about how the precision of the final computation will change based on local precision changes.</p>



<a name="194606026"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/floating%20point%20semantics/near/194606026" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Amanieu <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/floating.20point.20semantics.html#194606026">(Apr 19 2020 at 16:26)</a>:</h4>
<p>One idea I had was to allow <code>undef</code> in the FP domain and <code>freeze</code> values when we convert them to integers. The idea is that we only directly rely on integers for memory safety. However I'm a bit uncertain of how that would work with implicit and explicit transmutes.</p>



<a name="194606037"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/floating%20point%20semantics/near/194606037" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/floating.20point.20semantics.html#194606037">(Apr 19 2020 at 16:26)</a>:</h4>
<blockquote>
<p>So perhaps the conclusion is that all "fast-math" optimizations are unsafe? And it's not the kind of unsafe where a careful programmer can avoid UB.</p>
</blockquote>
<p>Agreed. the only formal model of fast-math I know is indeed using non-determinism as you also allude to, and to avoid UB the programmer needs some way to mark where the non-determinism has to "end" -- something like <code>freeze</code>. (As <span class="user-mention" data-user-id="143274">@Amanieu</span> says they could be implicit in a cast, too.)</p>



<a name="194607071"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/floating%20point%20semantics/near/194607071" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hanna Kruppe <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/floating.20point.20semantics.html#194607071">(Apr 19 2020 at 16:46)</a>:</h4>
<p>This is an interesting direction, but since branch/select conditions are also safety relevant and need to be frozen (artificial example: <code>if x &gt; y { free(ptr); } if x &lt;= y { ptr.write(1); }</code>), this seems to introduce a concerning number of freeze operations. If there's too many, their chilling effect on some optimizations might make "fast math" a net pessimization for a lot of code. Even if the freezes are programmer-controlled rather than automatic, the cognitive burden to figure out where it can and can't be omitted seems too great for people to use this ability correctly and precisely.</p>



<a name="194607589"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/floating%20point%20semantics/near/194607589" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hanna Kruppe <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/floating.20point.20semantics.html#194607589">(Apr 19 2020 at 16:57)</a>:</h4>
<p>That example is actually pretty bad but <em>waves hands</em></p>



<a name="194655103"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/floating%20point%20semantics/near/194655103" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hanna Kruppe <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/floating.20point.20semantics.html#194655103">(Apr 20 2020 at 10:08)</a>:</h4>
<p>Hmmm, but some value-changing optimizations are licensed by default, specifically those that change the bits of NaN results (sign, signaling/quiet, payload). Wouldn't those technically be subject to the same problem? Only a few niche operations can transport those differences to the integer domain (variations of transmutes, <code>is_sign_positive</code>, and  <code>copySign</code>) but hypothetically there should be soundness issues involving those lurking in current Rust.</p>



<a name="194705065"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/floating%20point%20semantics/near/194705065" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/floating.20point.20semantics.html#194705065">(Apr 20 2020 at 17:06)</a>:</h4>
<p>NaN changes are easy, we can just say that typed copies of floats do not preserve NaN bits</p>



<a name="194705083"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/floating%20point%20semantics/near/194705083" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/floating.20point.20semantics.html#194705083">(Apr 20 2020 at 17:06)</a>:</h4>
<p>so that's a lot like padding</p>



<a name="194715540"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/floating%20point%20semantics/near/194715540" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/floating.20point.20semantics.html#194715540">(Apr 20 2020 at 18:36)</a>:</h4>
<p>People could get upset with you there. Some people use those NaN bits. Also, <em>actually</em> doing that in practice is more costly than just unconditionally copying all four bytes, so if you're never going to do it anyway, don't claim that it might happen.</p>



<a name="194740300"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/floating%20point%20semantics/near/194740300" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/floating.20point.20semantics.html#194740300">(Apr 20 2020 at 22:16)</a>:</h4>
<p>but we do it sometimes. LLVM will clobber the NaN bits under some circumstances.</p>



<a name="194740314"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/floating%20point%20semantics/near/194740314" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/floating.20point.20semantics.html#194740314">(Apr 20 2020 at 22:16)</a>:</h4>
<p>pretending this does not happen is just going to make people sad</p>



<a name="194740341"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/floating%20point%20semantics/near/194740341" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/floating.20point.20semantics.html#194740341">(Apr 20 2020 at 22:16)</a>:</h4>
<p>so I'd rather make people defensively use <code>u32</code>  instead of <code>f32</code> for moving their stuff around</p>



<a name="194740399"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/floating%20point%20semantics/near/194740399" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/floating.20point.20semantics.html#194740399">(Apr 20 2020 at 22:17)</a>:</h4>
<p>see for example <a href="https://github.com/rust-lang/rust/issues/55131" title="https://github.com/rust-lang/rust/issues/55131">https://github.com/rust-lang/rust/issues/55131</a></p>



<a name="194740422"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/floating%20point%20semantics/near/194740422" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/floating.20point.20semantics.html#194740422">(Apr 20 2020 at 22:17)</a>:</h4>
<p>so there's a high chance that those people that use these NaN bits just have broken code that happens to work with some luck.</p>



<a name="194786318"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/floating%20point%20semantics/near/194786318" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hanna Kruppe <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/floating.20point.20semantics.html#194786318">(Apr 21 2020 at 10:56)</a>:</h4>
<p>LLVM will happily eliminate bitcasts and roundtrips through memory, so idk if focusing on typed copies will work. Like, <code>let bits = f.to_bits(); ptr::write(p1, bits); ptr::write(p2, bits);</code> should result in essentially the same IR as <code>ptr::write(p1.cast(), f); ptr::write(p2.cast(), f);</code> after a few cleanup passes.</p>



<a name="194793865"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/floating%20point%20semantics/near/194793865" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/floating.20point.20semantics.html#194793865">(Apr 21 2020 at 12:24)</a>:</h4>
<p>LLVM will happily eliminate int-ptr-casts and it is <a href="https://bugs.llvm.org/show_bug.cgi?id=34548" title="https://bugs.llvm.org/show_bug.cgi?id=34548">wrong in doing so</a>. maybe this is similar?</p>



<a name="194793989"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/floating%20point%20semantics/near/194793989" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/floating.20point.20semantics.html#194793989">(Apr 21 2020 at 12:25)</a>:</h4>
<p>I mean we could just say that the NaN result of a division (or any other NaN-producing operation) has non-det sign and payload, but is that sufficient to explain all behavior?</p>



<a name="194794082"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/floating%20point%20semantics/near/194794082" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hanna Kruppe <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/floating.20point.20semantics.html#194794082">(Apr 21 2020 at 12:26)</a>:</h4>
<p>It's not specifically divisions, it can happen with essentially any FP computation that results in NaN</p>



<a name="194794400"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/floating%20point%20semantics/near/194794400" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hanna Kruppe <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/floating.20point.20semantics.html#194794400">(Apr 21 2020 at 12:29)</a>:</h4>
<p>While you could argue for a semantics where int-&gt;float bitcasts can't be removed because they have implications for per-use nondeterministism, realistically this is leading to far fewer actual miscompiles than int-ptr-casts, so I am not hopeful that this perspective will appeal to LLVM.</p>



<a name="194831433"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/floating%20point%20semantics/near/194831433" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/floating.20point.20semantics.html#194831433">(Apr 21 2020 at 16:56)</a>:</h4>
<p>So...I skipped this thread. <span class="user-mention" data-user-id="124289">@Hanna Kruppe</span> does this in any way represent a kind of "blocking objection" on your part to <a href="https://github.com/rust-lang/rust/issues/71269" title="https://github.com/rust-lang/rust/issues/71269">#71269</a>?</p>



<a name="194831643"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/floating%20point%20semantics/near/194831643" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hanna Kruppe <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/floating.20point.20semantics.html#194831643">(Apr 21 2020 at 16:58)</a>:</h4>
<p>Not at all. The thread started with a question related to that PR, but that was settled quickly and everything since then has been unrelated to saturating int-&gt;float casts.</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>